﻿using CommonLibrary;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Core;
using Windows.Media.Editing;
using Windows.Media.Effects;
using Windows.Media.MediaProperties;
using Windows.Media.Transcoding;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x804 上介绍了“空白页”项模板

namespace EasyVideo {
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page {
        public MainPage() {
            this.InitializeComponent();
            Init();
            lb_视频.ItemsSource = _VideoClips;
            lb_Subtitles.ItemsSource = _Subtitles;
        }

        //初始化
        private void Init() {
            composition = new MediaComposition();
            MediaClip emptyClip = MediaClip.CreateFromColor(Colors.Black, new TimeSpan(0, 3, 0));
            composition.Clips.Add(emptyClip);
            //mediaPlayerElement.Position = TimeSpan.Zero;
            //mediaStreamSource = composition.GeneratePreviewMediaStreamSource((int)mediaPlayerElement.ActualWidth, (int)mediaPlayerElement.ActualHeight);
            //mediaPlayerElement.SetMediaStreamSource(mediaStreamSource);
        }

        ObservableCollection<VideoClip> _VideoClips = new ObservableCollection<VideoClip>();
        ObservableCollection<Subtitle> _Subtitles = new ObservableCollection<Subtitle>();
        private MediaComposition composition;
        private MediaStreamSource mediaStreamSource;

        protected override void OnNavigatedFrom(NavigationEventArgs e) {
            mediaPlayerElement.Source = null;
            mediaStreamSource = null;
            base.OnNavigatedFrom(e);
        }

        private void tbn_视频_Click(object sender, RoutedEventArgs e) {
            tbn_视频.IsChecked = true;
            tbn_特效.IsChecked = false;
            tbn_字幕.IsChecked = false;
            lb_视频.Visibility = Visibility.Visible;
            panel_Subtitles.Visibility = Visibility.Collapsed;
        }

        private void tbn_字幕_Click(object sender, RoutedEventArgs e) {
            tbn_视频.IsChecked = false;
            tbn_特效.IsChecked = false;
            tbn_字幕.IsChecked = true;
            lb_视频.Visibility = Visibility.Collapsed;
            panel_Subtitles.Visibility = Visibility.Visible;
        }

        private void tbn_特效_Click(object sender, RoutedEventArgs e) {
            tbn_视频.IsChecked = false;
            tbn_特效.IsChecked = true;
            tbn_字幕.IsChecked = false;
            lb_视频.Visibility = Visibility.Collapsed;
            panel_Subtitles.Visibility = Visibility.Collapsed;
        }

        private async void lb_视频_Drop(object sender, DragEventArgs e) {
            if (e.DataView.Contains(StandardDataFormats.StorageItems)) {
                var items = await e.DataView.GetStorageItemsAsync();
                if (items != null && items.Any()) {
                    await AddClip(items);
                    CreateOverlays();
                }
            }
        }

        private void lb_视频_DragOver(object sender, DragEventArgs e) {
            e.AcceptedOperation = DataPackageOperation.Copy;
            e.DragUIOverride.Caption = "拖放此处添加";
        }

        private async Task AddClip(IReadOnlyList<IStorageItem> items) {
            foreach (var item in items) {
                VideoClip vc = new VideoClip();
                vc.Title = item.Name;
                vc.Path = item.Path;
                var videoClip = await MediaClip.CreateFromFileAsync(item as StorageFile);
                vc.Clip = videoClip;
                _VideoClips.Add(vc);
            }
        }
        List<Subtitle> subtitles = new List<Subtitle>();
        private void CreateOverlays() {
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 1), EndTime = new TimeSpan(1000 * 3), Text = "我是测试字幕!" });
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 4), EndTime = new TimeSpan(1000 * 7), Text = "换字幕了 哈哈哈" });
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 7), EndTime = new TimeSpan(1000 * 11), Text = "再换个字幕试试看" });
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 12), EndTime = new TimeSpan(1000 * 15), Text = "lalalalallalal" });
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 18), EndTime = new TimeSpan(1000 * 23), Text = "fasfadfadfadsfs" });
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 25), EndTime = new TimeSpan(1000 * 28), Text = "再ssss试试s看" });
            subtitles.Add(new Subtitle() { BeginTime = new TimeSpan(1000 * 31), EndTime = new TimeSpan(1000 * 38), Text = "再ss试5555555看" });
            if (_VideoClips.Count > 0) {
                composition = new MediaComposition();
                composition.Clips.Add(_VideoClips[0].Clip);
                var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.BaseVideoEffect", new PropertySet() { { "BlurAmount", 3.0 } });
                videoEffectDefinition.Properties.Add("Subtitles", subtitles);
                _VideoClips[0].Clip.VideoEffectDefinitions.Add(videoEffectDefinition);
            }

            for (int i = 1; i < _VideoClips.Count; i++) {

                // Overlay video in upper left corner, retain its native aspect ratio
                Rect videoOverlayPosition;
                var encodingProperties = _VideoClips[i].Clip.GetVideoEncodingProperties();
                videoOverlayPosition.Height = mediaPlayerElement.ActualHeight / 3;
                videoOverlayPosition.Width = (double)encodingProperties.Width / (double)encodingProperties.Height * videoOverlayPosition.Height;
                videoOverlayPosition.X = 0;
                videoOverlayPosition.Y = 0;

                var videoOverlay = new MediaOverlay(_VideoClips[i].Clip);
                videoOverlay.Position = videoOverlayPosition;
                videoOverlay.Opacity = 0.75;

                var overlayLayer = new MediaOverlayLayer();
                overlayLayer.Overlays.Add(videoOverlay);
                composition.OverlayLayers.Add(overlayLayer);
            }




            // Render to MediaElement
            mediaPlayerElement.Position = TimeSpan.Zero;
            mediaStreamSource = composition.GeneratePreviewMediaStreamSource((int)mediaPlayerElement.ActualWidth, (int)mediaPlayerElement.ActualHeight);
            mediaPlayerElement.SetMediaStreamSource(mediaStreamSource);
            //rootPage.NotifyUser("Overlays created", NotifyType.StatusMessage);
        }

        //导出视频
        private async void Button_Click(object sender, RoutedEventArgs e) {
            var picker = new Windows.Storage.Pickers.FileSavePicker();
            picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
            picker.FileTypeChoices.Add("MPEG4", new List<string> { ".mp4" });
            Windows.Storage.StorageFile pickedFile = await picker.PickSaveFileAsync();
            if (pickedFile == null) {
                //ShowErrorMessage("File picking cancelled");
                return;
            }
            MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);
            profile.Video.Bitrate = 330;
            profile.Audio.BitsPerSample = 0;
            var saveOperation = composition.RenderToFileAsync(pickedFile, MediaTrimmingPreference.Fast, profile);

            saveOperation.Progress = new AsyncOperationProgressHandler<TranscodeFailureReason, double>(async (info, progress) => {
                await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() => {
                    txt_out.Text = string.Format("Saving file... 进度: {0:F0}%", progress);
                }));
            });
        }

        private void btn_play_Click(object sender, RoutedEventArgs e) {
            mediaPlayerElement.Play();
        }

        private void btn_stop_Click(object sender, RoutedEventArgs e) {
            mediaPlayerElement.Stop();
        }

        private void lb_视频_RightTapped(object sender, RightTappedRoutedEventArgs e) {
            FrameworkElement senderElement = sender as FrameworkElement;
            lb_Menu.ShowAt(sender as UIElement, e.GetPosition(sender as UIElement));
        }

        private void MenuFlyoutItem_Click1(object sender, RoutedEventArgs e) {
            VideoClip vc = lb_视频.SelectedItem as VideoClip;
            if (vc != null) {
                composition.Clips.Clear();
                MediaClip emptyClip = MediaClip.CreateFromColor(Colors.Black, new TimeSpan(0, 0, vc.Clip.TrimmedDuration.Seconds + 10));
                composition.Clips.Add(emptyClip);

                Rect videoOverlayPosition;
                var encodingProperties = vc.Clip.GetVideoEncodingProperties();
                videoOverlayPosition.Height = mediaPlayerElement.ActualHeight;
                videoOverlayPosition.Width = (double)encodingProperties.Width / (double)encodingProperties.Height * videoOverlayPosition.Height;
                videoOverlayPosition.X = 0;
                videoOverlayPosition.Y = 0;

                var videoOverlay = new MediaOverlay(vc.Clip);
                videoOverlay.Delay = new TimeSpan(0, 0, 10);
                videoOverlay.Position = videoOverlayPosition; //设置视频层位置
                videoOverlay.Opacity = 0.75; //设置视频层透明度

                var overlayLayer = new MediaOverlayLayer();
                overlayLayer.Overlays.Add(videoOverlay);
                composition.OverlayLayers.Add(overlayLayer);

                mediaPlayerElement.Position = TimeSpan.Zero;
                mediaStreamSource = composition.GeneratePreviewMediaStreamSource((int)mediaPlayerElement.ActualWidth, (int)mediaPlayerElement.ActualHeight);
                mediaPlayerElement.SetMediaStreamSource(mediaStreamSource);
            }
        }

        private void MenuFlyoutItem_Click2(object sender, RoutedEventArgs e) {

        }

        private void btn_AddSubtitle_Click(object sender, RoutedEventArgs e) {
            Subtitle sub = new Subtitle();
            sub.Text = "...";
            _Subtitles.Add(sub);
        }

        private void btn_DeleteSubtitle_Click(object sender, RoutedEventArgs e) {
            Subtitle sub = lb_Subtitles.SelectedItem as Subtitle;
            if (sub != null) {
                _Subtitles.Remove(sub);
            }
        }
    }
}
